from cmd import Cmd
import json
import os
import subprocess
import socket
import datetime, time

def isct(a, b):
    for i in range(len(a)):
        if a[i] != 'x' and b[i] != 'x' and a[i] != b[i]:
            return False
    return True

class Backend:
    def __init__(self, hs, port):
        self.hs = hs
        self.port = port
        self.socket = None

    def send(self, data):
        if type(data).__name__ != 'list':
            data = [data]
        for d in data:
            command = json.dumps(d, indent=1)
            print "sending command ", command
            self.socket.send(command)
            response = self.socket.recv(1024)
            print "received response:", response
            return response

class LB():
    def __init__(self):
        self.backends = []

    def connect(self):
        for b in self.backends:
            b.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            b.socket.connect(('127.0.0.1', b.port))

    def do_lb(self, data):
        for b in self.backends:
            for d in data:
                if d['method'] == 'add_rule' and isct(b.hs, d['params']['match']):
                    print 'send to %d at: %s' % (b.port, datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f'))
                    b.send(d)

class Eval(Cmd):
    prompt = 'cbeval> '

    def __init__(self):
        Cmd.__init__(self)
        self.lb = LB()

    def do_init(self, line):
        if line == '':
            line = 'datasets/stanford/setting.json'
        with open(line) as f:
            data = json.load(f)
            for b in data['backends']:
                if b['type'] == 'netplumber':
                    os.system('./backends/net_plumber/Ubuntu-NetPlumber-Release/net_plumber --load ./datasets/stanford/stanford_json_rules --server 0.0.0.0 %d --hdr-len %d --policy %s --filter %s > out/%d.dat&' % (b['port'], b['hdr_len'], b['policy'], b['hs'], b['port']))
                    be = Backend(b['hs'], b['port'])
                    self.lb.backends.append(be)
            time.sleep(5)
            self.lb.connect()

    def do_lb(self, line):
        """feed events to load balancer"""
        file = line
        if file == '':
            file = 'datasets/stanford/batch.json'

        with open(file) as f:
            data = json.load(f)
            self.lb.do_lb(data)


    def do_exit(self, line):
        os.system('pkill net_plumber')
        return True

if __name__ == '__main__':
    eval = Eval()
    eval.cmdloop()